#!/usr/bin/env python
# -*- coding: utf-8 -*-

import datetime
import os
import shutil
import re
from utils import log
from config import etc
from controls import mongo
from controls import data_img_base_mysql
from utils import fdfs
from PIL import Image
import tempfile
from utils import util

''' when file process success return value:{ "ret":0, "msg": "ok", "res": {"imgid": 999999, "group": 9999, "path": "xxxx", "ext": "jpg"}}}
    when file process failure return value:{  "ret":1, "msg": "ng",  "res":  {}}
'''
def file_upload(meta) :
    upload_path=os.path.join( os.path.dirname(etc.path_img), '' )
    failed_path=os.path.join( os.path.dirname(etc.path_img_failed), '' )

    raw_name = meta['filename']
    imgid = mongo.count_imgid()
    if not imgid :
        log.e( 'imgid fetching error' )
        return { "ret" : 1, "msg" : "ng", "res" : {} }
    ext_name = raw_name.split('.').pop()
    dst_name = str(imgid) + '.' + ext_name
    if ext_name == raw_name :
        ext_name = ''
        dst_name = str(imgid)
    dst_path = os.path.join( upload_path, dst_name )
    # binary file
    with open( dst_path, 'wb' ) as up :
        up.write( meta['body'] )

    # upload to fdfs
    dst_res = fdfs.upload_file( imgid, dst_path, ext_name )
    if not dst_res :
        os.rename(dst_path, os.path.join(failed_path, dst_name)) 
    else :
        os.rename(dst_path, os.path.join(upload_path , 'saved', dst_name)) 

    if dst_res:
        dst_res['sizetype'] = 0

    if dst_res and data_img_base_mysql.add_img_base_item( dst_res ) :
        return { "ret" : 0, "msg" : "ok", "res" : dst_res }
    else :
        return { "ret" : 1, "msg" : "ng", "res" : {} }

''' when file process failure return value:{  "ret":1, "msg": "ng",  "res":  {}}
    when file process success, image file will store raw file, 300x300 and 100x100, 
    return value:{ "ret":0, "msg": "ok", "res": {"imgid": 999999, "group": 9999, "path": "xxxx", "ext": "jpg"}}}
'''
def img_file_upload(meta) :
    upload_path=os.path.join( os.path.dirname(etc.path_img), '' )
    failed_path=os.path.join( os.path.dirname(etc.path_img_failed), '' )

    raw_name = meta['filename']
    imgid = mongo.count_imgid()
    if not imgid :
        log.e( 'imgid fetching error' )
        return { "ret" : 1, "msg" : "ng", "res" : {} }
    ext_name = raw_name.split('.').pop()
    prefix_name_300 = '_300'
    prefix_name_100 = '_100'
    dst_name = str(imgid) + '.' + ext_name
    thb_name_300 = str(imgid) + prefix_name_300 + '.' + ext_name
    thb_name_100 = str(imgid) + prefix_name_100 + '.' + ext_name
    if ext_name == raw_name :
        ext_name = ''
        dst_name = str(imgid)
        thb_name_300 = str(imgid) + prefix_name_300
        thb_name_100 = str(imgid) + prefix_name_100
    dst_path = os.path.join( upload_path, dst_name )
    thb_path_300 = os.path.join( upload_path, thb_name_300 )
    thb_path_100 = os.path.join( upload_path, thb_name_100 )
    # binary file
    with open( dst_path, 'wb' ) as up :
        up.write( meta['body'] )
    tf = tempfile.NamedTemporaryFile()
    tf.write( meta['body'] )
    tf.seek( 0 )
    # create 300 thumb file
    img_file = Image.open( dst_path )
    img_size = img_file.size
    pix_x, pix_y = util.get_img_pixs(300, img_size[0], img_size[1] )
    #log.i('x:'+str(pix_x) +', y:' +str(pix_y))
    img_file.thumbnail( (pix_x, pix_y), resample=1 )
    img_file.save( thb_path_300 )
    img_file.thumbnail( (pix_x/3, pix_y/3), resample=1 )
    img_file.save( thb_path_100 )
    tf.close()
    
    # upload to fdfs
    '''fdfs.upload_file's result
        res = {
                'imgid' : p_imgid ,
                'group' : res_group ,
                'path' : res_file_id.split('.',1)[0] ,
                'ext' : p_ext_name ,
                'file_id' : res_file_id ,
            }
    '''
    dst_res = fdfs.upload_file( imgid, dst_path, ext_name )
    if not dst_res :
        os.rename(dst_path, os.path.join(failed_path, dst_name)) 
    else :
        # move file to save fold
        os.rename(dst_path, os.path.join(upload_path , 'saved', dst_name)) 

    thb_res = fdfs.upload_slave_file( imgid, dst_res['file_id'], thb_path_300, prefix_name_300, ext_name )
    if not thb_res :
        os.rename(thb_path_300, os.path.join(failed_path , thb_name_300)) 
    else :
        os.rename(thb_path_300, os.path.join(upload_path , 'saved', thb_name_300)) 

    thb_res_100 = fdfs.upload_slave_file( imgid, dst_res['file_id'], thb_path_100, prefix_name_100, ext_name )
    if not thb_res_100 :
        os.rename(thb_path_100, os.path.join(failed_path , thb_name_100)) 
    else :
        os.rename(thb_path_100, os.path.join(upload_path , 'saved', thb_name_100)) 

    log.i(dst_res)
    if dst_res:
        dst_res['sizetype'] = 1

    if dst_res and data_img_base_mysql.add_img_base_item( dst_res ) :
        #self.write( json.dumps(dst_res) + '\n' + json.dumps(thb_res) +'\n'+ json.dumps(thb_res_100) )
        return { "ret" : 0, "msg" : "ok", "res" : dst_res }
    else :
        return { "ret" : 1, "msg" : "ng", "res" : {} }


''' when file process failure return value:{  "ret":1, "msg": "ng",  "res":  {}}
    when file process success, image file will store raw file, 300x300 and 100x100, 
    return value:{ "ret":0, "msg": "ok", "res": {"imgid": 999999, "group": 9999, "path": "xxxx", "ext": "jpg"}}}
'''
def img_file_upload_by_filename(filepath, filename) :

    imgid = mongo.count_imgid()
    if not imgid :
        log.e( 'imgid fetching error' )
        return { "ret" : 1, "msg" : "ng", "res" : {} }
    ext_name = filename.split('.').pop()
    prefix_name_300 = '_300'
    prefix_name_100 = '_100'
    #dst_name = str(imgid) + '.' + ext_name
    dst_name = filename
    thb_name_300 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_300 + '.' + ext_name
    thb_name_100 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_100 + '.' + ext_name
    if ext_name == filename :
        ext_name = ''
        thb_name_300 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_300
        thb_name_100 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_100
    dst_path = os.path.join( filepath, dst_name )
    thb_path_300 = os.path.join( filepath, thb_name_300 )
    thb_path_100 = os.path.join( filepath, thb_name_100 )
    # binary file
    #with open( dst_path, 'wb' ) as up :
    #    up.write( meta['body'] )
    tf = tempfile.NamedTemporaryFile()
    tf.write( dst_path )
    tf.seek( 0 )
    # create 300 thumb file
    img_file = Image.open( dst_path )
    img_size = img_file.size
    pix_x, pix_y = util.get_img_pixs(300, img_size[0], img_size[1] )
    img_file.thumbnail( (pix_x, pix_y), resample=1 )
    img_file.save( thb_path_300 )
    img_file.thumbnail( (pix_x/3, pix_y/3), resample=1 )
    img_file.save( thb_path_100 )
    tf.close()
    
    # upload to fdfs
    '''fdfs.upload_file's result
        res = {
                'imgid' : p_imgid ,
                'group' : res_group ,
                'path' : res_file_id.split('.',1)[0] ,
                'ext' : p_ext_name ,
                'file_id' : res_file_id ,
            }
    '''
    dst_res = fdfs.upload_file( imgid, dst_path, ext_name )

    thb_res = fdfs.upload_slave_file( imgid, dst_res['file_id'], thb_path_300, prefix_name_300, ext_name )

    thb_res_100 = fdfs.upload_slave_file( imgid, dst_res['file_id'], thb_path_100, prefix_name_100, ext_name )

    log.i(dst_res)
    data_img_base_mysql.create_img_base_table_if_not_exist()
    if dst_res:
        dst_res['sizetype'] = 1

    if dst_res and data_img_base_mysql.add_img_base_item( dst_res ) :
        #self.write( json.dumps(dst_res) + '\n' + json.dumps(thb_res) +'\n'+ json.dumps(thb_res_100) )
        return { "ret" : 0, "msg" : "ok", "res" : dst_res }
    else :
        return { "ret" : 1, "msg" : "ng", "res" : {} }

'''
upload city's map file
fdfs.upload_file's result
    res = {
            'imgid' : p_imgid ,
            'group' : res_group ,
            'path' : res_file_id.split('.',1)[0] ,
            'ext' : p_ext_name ,
            'file_id' : res_file_id ,
        }
'''        
def map_file_upload(meta, cityid) :

    if not meta :
        log.e( 'map file content empty' )
        return False

    upload_path=os.path.join( os.path.dirname(etc.path_map), '' )
    saved_path =os.path.join( os.path.dirname(etc.path_map_saved), '' )
    failed_path=os.path.join( os.path.dirname(etc.path_map_failed), '' )
    
    raw_name = meta['filename']
    ext_name = raw_name.split('.').pop()
    # cityid_YYYYmmdd_HHMMSS_raw_name
    dst_name = str(cityid) +'_' + datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + raw_name
    if ext_name == raw_name :
        ext_name = ''
    dst_path = os.path.join( upload_path, dst_name )
    # binary file
    with open( dst_path, 'wb' ) as up :
        up.write( meta['body'] )
    
    # upload to fdfs
    '''fdfs.upload_file's result
        res = {
                'imgid' : 0 ,
                'group' : res_group ,
                'path' : res_file_id.split('.',1)[0] ,
                'ext' : p_ext_name ,
                'file_id' : res_file_id ,
            }
    '''
    # parameter 0 is not used in fdfs.upload_file()
    dst_res = fdfs.upload_file( 0, dst_path, ext_name )
    log.i(dst_res)
    if not dst_res :
        os.rename(dst_path, os.path.join(failed_path, dst_name)) 
        log.e('fdfs upload map file failed, file path:' + os.path.join(failed_path, dst_name))
    else :
        # move file to save fold
        os.rename(dst_path, os.path.join(saved_path , dst_name)) 

    return dst_res


def local_file_upload(relative_path, raw_name, city_id):
    upload_path = os.path.join(os.path.dirname(etc.path_map), '')
    saved_path = os.path.join(os.path.dirname(etc.path_map_saved), '')
    failed_path = os.path.join(os.path.dirname(etc.path_map_failed), '')

    src_path = os.path.join(etc.path_seafile_root, relative_path, raw_name)

    ext_name = raw_name.split('.').pop()
    # cityid_YYYYmmdd_HHMMSS_raw_name
    dst_name = str(city_id) + '_' + datetime.datetime.now().strftime('%Y%m%d_%H%M%S') + raw_name
    dst_path = os.path.join(upload_path, dst_name)
    if ext_name != 'json':
        shutil.copy(src_path, dst_path)
    else:
        with open(dst_path, 'wb') as up:
            with open(src_path, 'r') as rfp:
                up.write(util.get_utf8_str(rfp.read()))
    # with open(dst_path, 'wb') as up :
    #     up.write( meta['body'] )

    # upload to fdfs
    '''fdfs.upload_file's result
        res = {
                'imgid' : 0 ,
                'group' : res_group ,
                'path' : res_file_id.split('.',1)[0] ,
                'ext' : p_ext_name ,
                'file_id' : res_file_id ,
            }
    '''
    # parameter 0 is not used in fdfs.upload_file()
    dst_res = fdfs.upload_file(0, dst_path, ext_name)
    log.i(dst_res)
    if not dst_res:
        os.rename(dst_path, os.path.join(failed_path, dst_name))
        log.e('fdfs upload map file failed, file path:' + os.path.join(failed_path, dst_name))
    else:
        # move file to save fold
        os.rename(dst_path, os.path.join(saved_path, dst_name))

    return dst_res


def img_file_upload_by_filename_v2(filepath, filename):
    """
    v1将生成的略缩图文件写入源文件夹，v2将之写入etc/path_img_v2
    主要用于product和card的图片
    :param filepath:
    :param filename:
    :return:
    """
    imgid = mongo.count_imgid()
    if not imgid:
        log.e('imgid fetching error')
        return {"ret": 1, "msg": "ng", "res": {}}
    
    ext_name = filename.split('.').pop()
    prefix_name_300 = '_300'
    prefix_name_100 = '_100'
    # dst_name = str(imgid) + '.' + ext_name
    dst_name = filename
    thb_name_300 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_300 + '.' + ext_name
    thb_name_100 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_100 + '.' + ext_name
    if ext_name == filename:
        ext_name = ''
        thb_name_300 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_300
        thb_name_100 = filename.split('.')[0] + '_' + str(imgid) + prefix_name_100
    dst_path = os.path.join(filepath, dst_name)
    thb_path_300 = os.path.join(etc.path_slave_img, thb_name_300)
    thb_path_100 = os.path.join(etc.path_slave_img, thb_name_100)
    # create 300 thumb file
    img_file = Image.open(dst_path)
    img_size = img_file.size
    pix_x, pix_y = util.get_img_pixs(300, img_size[0], img_size[1])
    img_file.thumbnail((pix_x, pix_y), resample=1)
    img_file.save(thb_path_300)
    img_file.thumbnail((pix_x / 3, pix_y / 3), resample=1)
    img_file.save(thb_path_100)
    
    # upload to fdfs
    dst_res = fdfs.upload_file(imgid, dst_path, ext_name)
    
    thb_res = fdfs.upload_slave_file(imgid, dst_res['file_id'], thb_path_300, prefix_name_300, ext_name)
    
    thb_res_100 = fdfs.upload_slave_file(imgid, dst_res['file_id'], thb_path_100, prefix_name_100, ext_name)
    
    log.i(dst_res)
    data_img_base_mysql.create_img_base_table_if_not_exist()

    if dst_res:
        dst_res['sizetype'] = 1

    if dst_res and data_img_base_mysql.add_img_base_item(dst_res):
        # self.write( json.dumps(dst_res) + '\n' + json.dumps(thb_res) +'\n'+ json.dumps(thb_res_100) )
        return {"ret": 0, "msg": "ok", "res": dst_res}
    else:
        return {"ret": 1, "msg": "ng", "res": {}}


def get_100_size_imglink(imglink):
    return re.sub("(.*)(\.[a-z0-9]{1,4})$", r"\1_100\2", imglink)


def get_300_size_imglink(imglink):
    return re.sub("(.*)(\.[a-z0-9]{1,4})$", r"\1_300\2", imglink)